using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace IUPUI.StellarResults.Client.UIElements
{
	/// <summary>
	/// Represents an <see cref="AstronomicalObject"/> in an <see cref="AstronomicalObjectsLegendControl"/>.
	/// </summary>
	public partial class AstronomicalObjectLegendItem : UserControl
	{
		#region Private Properties
		private Simulation m_Simulation;
		private AstronomicalObject m_AstronomicalObject;
		private bool m_ContextMenuOpened = false;
		#endregion Private Properties

		#region Public Properties
		/// <summary>
		/// Gets or sets the simulation.
		/// </summary>
		/// <value>The simulation.</value>
		[Browsable(false)]
		public Simulation Simulation
		{
			get
			{
				return m_Simulation;
			}
			set
			{
				if (m_Simulation != value)
				{
					m_Simulation = value;
				}
			}
		}

		/// <summary>
		/// Gets or sets the astronomical object.
		/// </summary>
		/// <value>The astronomical object.</value>
		[Browsable(false)]
		public AstronomicalObject AstronomicalObject
		{
			get
			{
				return m_AstronomicalObject;
			}
			set
			{
				if (m_AstronomicalObject != value)
				{
					m_AstronomicalObject = value;
					m_AstronomicalObjectBindingSource.DataSource = value;

					m_TrackAtAllToolStripMenuItem.Text =
						String.Format(
						Properties.Resources.TrackObjectAtAllObservatories, 
						m_AstronomicalObject.Name);

					// Get full tooltip description for the object
					string description =
						String.Format(
							Properties.Resources.AstronomicalObjectLegendItemToolTip,
							m_AstronomicalObject.PositionType,
							System.Environment.NewLine,
							ININ.StringUtilities.ParsePascalCase(m_AstronomicalObject.AstronomicalObjectType.ToString()),
							m_AstronomicalObject.Description);

					m_ToolTip.SetToolTip(
						this, description);
					m_ToolTip.SetToolTip(
						m_AstronomicalObjectName, description);
				}
			}
		}
		#endregion Public Properties

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObjectLegendItem"/> class.
		/// </summary>
		public AstronomicalObjectLegendItem()
		{
			InitializeComponent();
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObjectLegendItem"/> class.
		/// </summary>
		/// <param name="astronomicalObject">The astronomical object.</param>
		public AstronomicalObjectLegendItem(
			AstronomicalObject astronomicalObject) : this()
		{
			AstronomicalObject = astronomicalObject;
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="AstronomicalObjectLegendItem"/> class.
		/// </summary>
		/// <param name="astronomicalObject">The astronomical object.</param>
		/// <param name="simulation">The simulation.</param>
		public AstronomicalObjectLegendItem(
			AstronomicalObject astronomicalObject,
			Simulation simulation)
			: this(astronomicalObject)
		{
			Simulation = simulation;
		}
		#endregion Constructors

		/// <summary>
		/// Raises the <see cref="E:System.Windows.Forms.Control.Paint"/> event.
		/// </summary>
		/// <param name="e">A <see cref="T:System.Windows.Forms.PaintEventArgs"/> that contains the event data.</param>
		protected override void OnPaint(PaintEventArgs e)
		{
			// Initialize
			Graphics g = e.Graphics;
			g.SmoothingMode = SmoothingMode.AntiAlias;
			Pen blackPen = new Pen(Color.Black);

			// Get representational color
			Color representationColor = Color.Black;
			try
			{
				representationColor = Color.FromName(
					m_AstronomicalObject.RepresentationColor);
			}
			catch(Exception)
			{
				representationColor = Color.Black;
			}
			Brush brush = new SolidBrush(representationColor);

			// Draw circle with the color that represents the object		
			g.FillEllipse(brush, 1, 1, 11, 11);
			g.DrawEllipse(blackPen, 1, 1, 11, 11);

			// Cleanup
			brush.Dispose();
			blackPen.Dispose();

			base.OnPaint(e);
		}
		/// <summary>
		/// Highlights the control.
		/// </summary>
		/// <param name="highlight">if set to <c>true</c> [highlight].</param>
		private void HighlightControl(
			bool highlight)
		{
			if (highlight)
			{
				this.BackColor = SystemColors.GradientActiveCaption;
			}
			else
			{
				this.BackColor = Color.Transparent;
			}
		}

		/// <summary>
		/// Sets all observatories to track an astronomical object.
		/// </summary>
		/// <param name="astronomicalObjectID">The astronomical object ID.</param>
		private void SetAllObservatoriesToTrack(
			string astronomicalObjectID)
		{
			ININ.Guard.ArgumentNotNullOrEmptyString(astronomicalObjectID, "astronomicalObjectID");

			if (m_Simulation != null)
			{
				// Set each observatory to track this object
				foreach (Observatory observatory in m_Simulation.Observatories)
				{
					if (observatory.IsPositionable)
					{
						observatory.AstronomicalObjectBeingTracked = astronomicalObjectID;
					}
				}
			}
		}

		#region Event Handlers
		/// <summary>
		/// Handles the Click event of the m_TrackAtAllToolStripMenuItem control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_TrackAtAllToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (m_AstronomicalObject != null)
			{
				SetAllObservatoriesToTrack(m_AstronomicalObject.ID);
			}
		}

		/// <summary>
		/// Handles the MouseEnter event of the AstronomicalObjectLegendItem control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void AstronomicalObjectLegendItem_MouseEnter(object sender, EventArgs e)
		{
			HighlightControl(true);
		}

		/// <summary>
		/// Handles the MouseLeave event of the AstronomicalObjectLegendItem control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void AstronomicalObjectLegendItem_MouseLeave(object sender, EventArgs e)
		{
			if (!m_ContextMenuOpened)
			{
				HighlightControl(false);
			}
		}

		/// <summary>
		/// Handles the Opened event of the m_ContextMenuStrip control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		private void m_ContextMenuStrip_Opened(object sender, EventArgs e)
		{
			m_ContextMenuOpened = true;
			HighlightControl(true);
		}

		/// <summary>
		/// Handles the Closed event of the m_ContextMenuStrip control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="System.Windows.Forms.ToolStripDropDownClosedEventArgs"/> instance containing the event data.</param>
		private void m_ContextMenuStrip_Closed(object sender, ToolStripDropDownClosedEventArgs e)
		{
			m_ContextMenuOpened = false;

			if (!new Rectangle(this.Location, this.Size).Contains(new Point(MousePosition.X, MousePosition.Y)))
			{
				HighlightControl(false);
			}
		}
		#endregion Event Handlers
	}
}
